/**
 * Octopus, an XMMS2 client.
 * Copyright (C) 2014 Octopus Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

namespace Octopus {
	public class Playback : Track {
		private int _volume;

		public signal void medialib_info_changed ();
		public signal void playback_status_stop ();
		public signal void playback_status_play ();
		public signal void playback_status_pause ();
		public signal void playback_playtime (int pos);
		public signal void playback_volume (int volume);

		public Playback () {
			Object ();
		}

		public void load_playback () {
			//callback current (now playing) id
			Global.get ().get_xmms_client ().get_xmms ().playback_current_id().notifier_set (on_playback_current_id);
			//broadcast on (future) changing id
			Global.get ().get_xmms_client ().get_xmms ().broadcast_playback_current_id ().notifier_set (on_playback_current_id);
			//status
			Global.get ().get_xmms_client ().get_xmms ().playback_status().notifier_set (on_playback_status);
			Global.get ().get_xmms_client ().get_xmms ().broadcast_playback_status ().notifier_set (on_playback_status);
			//playtime
			Global.get ().get_xmms_client ().get_xmms ().playback_playtime ().notifier_set (on_playback_playtime);
			Global.get ().get_xmms_client ().get_xmms ().signal_playback_playtime ().notifier_set (on_playback_playtime);
			//volume
			Global.get ().get_xmms_client ().get_xmms ().playback_volume_get ().notifier_set (on_playback_volume);
			Global.get ().get_xmms_client ().get_xmms ().broadcast_playback_volume_changed ().notifier_set (on_playback_volume);
		}

		private bool on_playback_current_id(Xmms.Value val) {
			int id;

			if (val.get_int(out id)) {
				//request medialib info
				Global.get ().get_xmms_client ().get_xmms ().medialib_get_info (id).notifier_set (on_medialib_info);
			}
			return true;
		}

		private bool on_playback_status(Xmms.Value val) {
			int status;

			val.get_int(out status);
			switch (status) {
				case Xmms.PlaybackStatus.STOP:  playback_status_stop (); break;
				case Xmms.PlaybackStatus.PLAY:  playback_status_play (); break;
				case Xmms.PlaybackStatus.PAUSE: playback_status_pause (); break;
				default: break;
			}
			return true;
		}

		private bool on_medialib_info (Xmms.Value propdict) {
			Xmms.Value val = propdict.propdict_to_dict ();

			set_values(val);
			medialib_info_changed ();

			return true;
		}

		private bool on_playback_playtime(Xmms.Value val) {
			//current playback position in ms
			int pos;

			if (val.get_int (out pos)) {
				playback_playtime (pos);
			}
			return true;
		}

		private bool on_playback_volume(Xmms.Value val) {
			unowned Xmms.DictIter iter;
			int total_volume = 0;
			int channels = 0;

			val.get_dict_iter (out iter);
			while (iter.valid ()) {
				unowned Xmms.Value volume;
				unowned string name;
				int tmp = 0;

				if (iter.pair (out name, out volume)) {
					if (volume.get_int (out tmp)) {
						total_volume += tmp;
						channels++;
					}
				}
				iter.next ();
			}

			if (channels > 0) {
				playback_volume ((int) (total_volume / channels * 1.0));
			}
			return true;
		}

		public void xmms_apply_volume (int volume) {
			_volume = volume;
			Global.get ().get_xmms_client ().get_xmms ().playback_volume_get ().notifier_set ((val) => {
				if (!val.is_error ()) {
					val.dict_foreach((key, val) => {
						Global.get ().get_xmms_client ().get_xmms ().playback_volume_set (key, _volume);
					});
				}
				return true;
			});
		}

		public void xmms_play () {
			Global.get ().get_xmms_client ().get_xmms ().playback_start ();
		}

		public void xmms_pause () {
			Global.get ().get_xmms_client ().get_xmms ().playback_pause ();
		}

		public void xmms_stop () {
			Global.get ().get_xmms_client ().get_xmms ().playback_stop ();
		}

		public void xmms_set_prev () {
			Global.get ().get_xmms_client ().get_xmms ().playlist_set_next_rel (-1);
			Global.get ().get_xmms_client ().get_xmms ().playback_tickle ();
		}

		public void xmms_set_next () {
			Global.get ().get_xmms_client ().get_xmms ().playlist_set_next_rel (1);
			Global.get ().get_xmms_client ().get_xmms ().playback_tickle ();
		}

		public void xmms_seek (uint pos) {
			Global.get ().get_xmms_client ().get_xmms ().playback_seek_ms(pos, Xmms.PlaybackSeekMode.SET);
		}
	}
}
